#include "Creature.h"
#include "STGEngine.h"
#include <Ogre.h>
#include "STGObjectManager.h"
using namespace Ogre;
//CCreature::CCreature() {
//    
//}
CCreature::CCreature(const std::string &name, const std::string &scriptName)
: GameObject(name, scriptName)
, mPower(1)
, mSpeed(100)
, mDefence(1)
, mLife(100)
, mMana(100)
{


}
CCreature::~CCreature() {
}


GameInst* CCreature::createInstance(const std::string &name) {
    GameInst *pInst = new CCreatureInst(this, name);
    mInstances.push_back(pInst);
    return pInst;
}

CCreatureInst::CCreatureInst(CCreature *pCreature, const std::string &name)
: GameInst(pCreature, name)
, mCurrentLife(pCreature->mLife)
, mCurrentMana(pCreature->mMana)
, mCurrentPower(pCreature->mPower)
, mCurrentSpeed(pCreature->mSpeed)
, mCurrentDefence(pCreature->mDefence)
{
    mEntity = CEngine::getSingletonPtr()->getSceneManager()->createBillboardSet(1);
    Ogre::BillboardSet* billboard = dynamic_cast<Ogre::BillboardSet*>(mEntity);
    billboard->createBillboard(Vector3::ZERO);
    billboard->setBillboardsInWorldSpace(false);
    billboard->setBillboardType(BBT_ORIENTED_COMMON);
    billboard->setCommonDirection(Vector3(0,1,0));
    billboard->setDefaultDimensions(100,100);
    billboard->setCullIndividually(false);
    if (pCreature->mTexture == "") {
        setMaterialName( "BaseWhite" );
    }
    else {
        setMaterialName(pCreature->mTexture);
    }
    mNode->attachObject(mEntity);
}

void CCreatureInst::setMaterialName(const std::string& name, const std::string& groupName) {
    dynamic_cast<Ogre::BillboardSet*>(mEntity)->setMaterialName(name, groupName);
}
CCreatureInst::~CCreatureInst() {
    //mEntity->detachFromParent();
    //OGRE_DELETE mEntity;
    //for (int i = 0; i != )
    for (size_t i = 0; i != mWeaponInsts.size(); ++i) {
        delete mWeaponInsts[i];
    }
    for (size_t i = 0; i != mSkillInsts.size(); ++i) {
        delete mSkillInsts[i];
    }    
}

void CCreatureInst::update( float dt )
{
    for(size_t i = 0; i != mWeaponInsts.size(); ++i) {
        if (mWeaponInsts[i])
            mWeaponInsts[i]->update(dt);
    }
    for(size_t i = 0; i != mSkillInsts.size(); ++i) {
        if (mSkillInsts[i])
            mSkillInsts[i]->update(dt);
    }
}

void CCreatureInst::addWeapon( CWeaponInst*pWeapon, size_t slot)
{
    if (slot >= mWeaponInsts.size()) {
        mWeaponInsts.resize(slot+1);
    }
    assert(pWeapon);
    pWeapon->setParent(this);
    mWeaponInsts[slot] = pWeapon;
    mWeaponInsts.push_back(pWeapon);
    //return pWeapon;
}
CWeaponInst* CCreatureInst::removeWeapon(const std::string &name)
{
    for (size_t i = 0; i != mWeaponInsts.size(); ++i) {
        if (name == mWeaponInsts[i]->mName){
            return removeWeapon(i);
        }
    }
    return NULL;
}
CWeaponInst* CCreatureInst::removeWeapon(size_t slot)
{
    assert(slot < mWeaponInsts.size());
    CWeaponInst *pInst = NULL;
    if (mWeaponInsts[slot]) {
        mWeaponInsts[slot]->setParent(NULL);
        std::swap(pInst, mWeaponInsts[slot]);
    }
    return pInst;
}

//==============================================================================
//
GameInst* CNPC::createInstance(const std::string &name) {
    GameInst *pInst = new CNPCInst(this, name);
    mInstances.push_back(pInst);
    return pInst;
}

CNPCInst::CNPCInst(CNPC *pObject, const std::string &name)
: CCreatureInst(pObject, name) {
}